{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "vocational-reliance",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据train_word_features已加载成功\n",
      "数据test_word_features已加载成功\n",
      "---第0次KF---\n",
      "---第1次KF---\n",
      "---第2次KF---\n",
      "---第3次KF---\n",
      "---第4次KF---\n",
      "---第5次KF---\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "111"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "############################### LightBGM Voting #######################################\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import logging\n",
    "#from sklearn.externals import joblib\n",
    "import joblib\n",
    "np.warnings.filterwarnings('ignore')\n",
    "\n",
    "from sklearn.model_selection import KFold\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.metrics import f1_score\n",
    "from lightgbm import LGBMClassifier\n",
    "import lightgbm as lgb\n",
    "import src.configs as config\n",
    "\n",
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = 'all'\n",
    "\n",
    "LOG_FORMAT = \"%(asctime)s - %(levelname)s - %(message)s\"\n",
    "DATE_FORMAT = \"%m/%d/%Y %H:%M:%S %p\"\n",
    "\n",
    "logging.basicConfig(filename='train.log', level=logging.INFO, format=LOG_FORMAT, datefmt=DATE_FORMAT)\n",
    "\n",
    "# load data set\n",
    "train_df = pd.read_csv(config.DATA_PATH + '/train_set.csv', sep='\\t')\n",
    "test_df = pd.read_csv(config.DATA_PATH + '/test_a.csv', sep='\\t', nrows=None)\n",
    "\n",
    "\n",
    "# # feature vectorization\n",
    "# vectorizer = TfidfVectorizer(ngram_range=(1, 3), max_features=50000)\n",
    "# vectorizer.fit(np.concatenate((train_df['text'].iloc[:].values,test_df['text'].iloc[:].values),axis=0))\n",
    "# config.DOP.save(vectorizer, \"tf_idf_model\", is_model=False)\n",
    "# vectorizer = config.DOP.load_data(\"tf_idf_model\")\n",
    "# train_word_features = vectorizer.transform(train_df['text'].iloc[:].values)\n",
    "# test_word_features = vectorizer.transform(test_df['text'].iloc[:].values)\n",
    "# config.DOP.save(train_word_features, \"train_word_features\", is_model=False)\n",
    "# config.DOP.save(test_word_features, \"test_word_features\", is_model=False)\n",
    "\n",
    "\n",
    "train_word_features = config.DOP.load_data(\"train_word_features\")\n",
    "test_word_features = config.DOP.load_data(\"test_word_features\")\n",
    "\n",
    "# parameters\n",
    "params={}\n",
    "params['n_estimators']=500\n",
    "params['subsample']=0.72\n",
    "params['colsample_bytree']=0.599\n",
    "params['reg_alpha']=0.001\n",
    "params['reg_lambda']=0.5\n",
    "params['boosting_type']='gbdt' #GradientBoostingDecisionTree\n",
    "params['objective']='multiclass' #Multi-class target feature\n",
    "params['metric']='multi_logloss' #metric for multi-class\n",
    "params['learning_rate']=0.088\n",
    "params['max_depth']=100\n",
    "params['num_leaves']=67\n",
    "params['min_child_samples']=21\n",
    "params['num_class']=14\n",
    "params['n_jobs'] = 10\n",
    "\n",
    "\n",
    "# train model\n",
    "X_train = train_word_features\n",
    "y_train = train_df['label']\n",
    "X_test = test_word_features\n",
    "\n",
    "KF = KFold(n_splits=6, random_state=1, shuffle=True) \n",
    "\n",
    "F1s = []\n",
    "\n",
    "# save the test result\n",
    "test_pred = np.zeros((X_test.shape[0], 1), int)  \n",
    "for KF_index, (train_index,valid_index) in enumerate(KF.split(X_train)):\n",
    "    print(f\"---第{KF_index}次KF---\")\n",
    "    logging.info(\"The No. {} cross validation begines...\".format(KF_index+1))\n",
    "\n",
    "    # divide train and valid dataset\n",
    "    x_train_, x_valid_ = X_train[train_index], X_train[valid_index]\n",
    "    y_train_, y_valid_ = y_train[train_index], y_train[valid_index]\n",
    "\n",
    "    # fit model\n",
    "    d_train=lgb.Dataset(x_train_, label=y_train_)\n",
    "    d_val = lgb.Dataset(x_valid_, label=y_valid_, reference=d_train) \n",
    "#     clf=lgb.train(params,d_train,num_boost_round=500,valid_sets=d_val,early_stopping_rounds=20)\n",
    "#     clf = config.DOP.load_model(f'my_LGBM_model_5cv_{KF_index}')\n",
    "    clf = joblib.load(config.SAVED_MODEL_PATH + f'/my_LGBM_model_5cv_{KF_index}.pkl')\n",
    "    # predict\n",
    "    val_pred = np.argmax(clf.predict(x_valid_, num_iteration=clf.best_iteration),axis=1)\n",
    "    F1 = f1_score(y_valid_, val_pred, average='macro')\n",
    "    logging.info(\"The F1 Score is：{}\".format(F1))\n",
    "    F1s.append(str(F1))\n",
    "    # save the test result 对结果编号\n",
    "    test_pred = np.column_stack((test_pred, np.argmax(clf.predict(X_test,num_iteration=clf.best_iteration),axis=1)))\n",
    "    \n",
    "    #save models\n",
    "    logging.info(\"Saving model...\")\n",
    "#     joblib.dump(clf, config.SAVED_MODEL_PATH + f'/my_LGBM_model_5cv_{KF_index}.pkl', compress=3)\n",
    "\n",
    "with open(config.PROCESSED_DATA_PATH + \"/F1.txt\", \"w\") as f:\n",
    "    f.write(\" \".join(F1s))\n",
    "    \n",
    "# get the final result according to the most votes\n",
    "logging.info(\"test_pred.shape: {}\".format(test_pred.shape))\n",
    "logging.info(\"The first column of test_pred is pure [0], removing...\")\n",
    "\n",
    "test_pred=test_pred[...,1:test_pred.shape[1]]\n",
    "\n",
    "logging.info(\"test_pred.shape: {}\".format(test_pred.shape))\n",
    "\n",
    "preds = []\n",
    "for i, test_list in enumerate(test_pred):\n",
    "    preds.append(np.argmax(np.bincount(test_list)))\n",
    "preds = np.array(preds)\n",
    "\n",
    "# store the final results\n",
    "df = pd.DataFrame()\n",
    "df['label'] = preds\n",
    "df.to_csv(config.PROCESSED_DATA_PATH + '/dalma_lgbm.csv', index=False)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
